"use strict";
/**
 * 数组哈希表 模仿数组的行为的哈希表 
 * @author huazai 2018 08-07
 * clear()
 * length
 * remove(key)
 * containsKey(key)
 */
function HashMapArray() {
	this.clear();
}

var p = HashMapArray.prototype;

p.clear = function() {
	this._keys = [];
	this._props = {};
};

p.getLength = function() {
	return this._keys.length;
};
try {
	Object.defineProperties(p, {
		length: {
			get: p.getLength
		}
	});
} catch(e) {}

//得到key对应的索引
p.getIndexByKey = function(key) {
	return this._keys.indexOf(key);
};

//得到键值value对应的索引
p.getIndexByValue = function(value) {
	var result = -1;
	var len = this._keys.length;
	if(len > 0) {
		for(var i = 0; i < len; i++) {
			if(this._props[this._keys[i]] == value) {
				result = i;
				break;
			}
		}
	}
	return result;
};

//得到一个key对应的值
p.getValue = function(key) {
	return this._props[key];
};

//得到一个下标对应的值 相当于数组下标
p.getValueAt = function(index) {
	return this._props[this._keys[index]];
};
//判断一个key是否存在 true为存在
p.containsKey = function($key) {
	var searchIndex = this._keys.indexOf($key);
	if(searchIndex >= 0) {
		//存在
		return true;
	}
	//			return _props[$key] != null;
	return false;
};

//得到所有的键值value的数值  没有数据内容的时候返回[]数组
p.values = function() {
	var result = [];
	var len = this._keys.length;
	if(len > 0) {
		for(var i = 0; i < len; i++) {
			result.push(this._props[this._keys[i]]);
		}
	}
	return result;
};

//返回键名key数组 没有数据内容的时候返回[]数组
p.keys = function() {
	return this._keys;
};

//删除对应的键值，并返回删除的元素 没有数据的时候为null
p.remove = function(key) {
	var result = null;
	var index = this._keys.indexOf(key);
	if(index > -1) {
		this._keys.splice(index, 1)[0];
		result = this._props[key];
		delete this._props[key];
	}
	return result;
};

//加入一个$key和$value值对 相同的key值会被删除 重新加入新的值 尾部加入
p.push = function(key, value) {
	var result = this.remove(key);
	this._props[key] = value;
	this._keys.push(key);
	if(result) {
		console.error("hash 添加元素的时候有重复元素被删除", result);
	}
	return result;
};

//加入一个$key和$value值对 相同的key值会被删除 从指定位置重新加入 超出则从尾部加入
p.pushAt = function(key, value, index) {
	if(index < 0) {
		index = this._keys.length + 1;
	}
	var result = this.remove(key);
	this._props[key] = value;
	this._keys.splice(index, 0, key);
	if(result) {
		console.error("hash 添加元素的时候有重复元素被删除", result);
	}
	return result;
};

//删除哈希表中第一个元素，并返回该元素。{key,value}值对
p.shift = function() {
	if(this._keys.length > 0) {
		var k = this._keys.shift();
		var v = this._props[k];
		delete this._props[k];
		return {
			key: k,
			value: v
		};
	}
	return null;
};

//删除哈希表中最后一个元素，并返回该元素。。{key,value}值对
p.pop = function() {
	if(this._keys.length > 0) {
		var k = this._keys.pop();
		var v = this._props[k];
		delete this._props[k];
		return {
			key: k,
			value: v
		};
	}
	return null;
};

//加入一个$key和$value值对 相同的key值会被删除 重新加入新的值 头部加入
p.unshift = function(key, value) {
	var result = this.remove(key);
	this._props[key] = value;
	this._keys.unshift(key);
	return result;
};

//将参数中指定的HashMapArray数据和本数据连接，并创建新的HashMapArray数组。
p.concat = function(mapArray) {
	var result = new HashMapArray();
	var arr, len, i, k, v;
	var _mapList = [this, mapArray];
	for(var m = 0; m < _mapList.length; m++) {
		var _map = _mapList[m];
		if(_map) {
			arr = _map.keys();
			len = _map.length;
			for(i = 0; i < len; i++) {
				k = arr[i];
				v = _map.getValue(k);
				result.push(k, v);
			}
		}
	}
	return result;
};
p.get = p.getValue;
p.put = p.push;
exports = module.exports = HashMapArray;